using System;
using System.Collections.Generic;
using System.Text;
using Xeml.Document.Contracts;
using Mpi.Common.Collections;
using System.Diagnostics;
using Xeml.Document;
using System.Linq;

namespace XemlUtilities.Indexing
{
    public sealed class SampleIndexer
    {

        #region Singleton pattern
        static readonly SampleIndexer instance = new SampleIndexer();

        static SampleIndexer()
        {
        }

        SampleIndexer()
        {


        }

        public static SampleIndexer Instance
        {
            get
            {
                return instance;
            }
        }
        #endregion

        private IDocument doc;
        private int currentIndx = 0;

        public void Init(IDocument doc)
        {
            if (this.doc != doc)
            {
                this.doc = doc;
                FindCurrentIndx();
            }
        }

        public int NextId()
        {
            lock (this)
            {
                this.currentIndx++;
            }
            return this.currentIndx;
        }

        public void NormalizeIndex()
        {
            //Dictionary<StoryBase, int> dict = new Dictionary<StoryBase, int>();
            //int c = 0;
            //GetSortedDtoryList(this.doc.StoryBoard.VirtualRoot, ref dict, ref c);
            List<Sample> samples = DocumentHelper.ExtractSamples(this.doc).ToList();
            SortedDictionary<long, SortedDictionary<int, SortedDictionary<int, Sample>>> sorted = new SortedDictionary<long, SortedDictionary<int, SortedDictionary<int, Sample>>>();


            foreach (Sample s in samples)
            {
                long tLong = s.TimePoint.Ticks;
                if (!sorted.ContainsKey(tLong))
                    sorted.Add(tLong, new SortedDictionary<int, SortedDictionary<int, Sample>>());
                int sIndx = this.doc.StoryBoard.IndexOf(s.Collection.Story);       //dict[s.Collection.Owner as StoryBase];
                if (!sorted[tLong].ContainsKey(sIndx))
                    sorted[tLong].Add(sIndx, new SortedDictionary<int, Sample>());
                int minPartId = Int16.MaxValue;
                foreach (Partition part in s.Partitions)
                {
                    minPartId = Math.Min(minPartId, part.Id);
                }
                //if(!sorted[tLong][sIndx].ContainsKey(minPartId))
                Debug.WriteLine("SampleIndexer: " + tLong + ", " + sIndx + ", " + minPartId); 
                sorted[tLong][sIndx].Add(minPartId, s);
            }

            int sampleIndx = 1;
            foreach (long l in sorted.Keys)
            {
                foreach (int i in sorted[l].Keys)
                {
                    foreach (int j in sorted[l][i].Keys)
                    {
                        sorted[l][i][j].Id = sampleIndx;
                        sampleIndx++;
                    }
                }
                //sorted[l].Id = sampleIndx;
                
            }
            this.currentIndx = sampleIndx;
            // this.doc.StoryBoard.VirtualRoot.
        }


        //private void GetSortedDtoryList(TreeNode<StoryBase> startNode, ref Dictionary<StoryBase, int> dict, ref int counter)
        //{

        //    for (int i = 0; i < startNode.SubNodeCount; i++)
        //    {
        //        dict.Add(startNode[i].Content, counter);
        //        counter++;
        //        GetSortedDtoryList(startNode[i], ref dict, ref counter);

        //    }
        //}


        private void FindCurrentIndx()
        {
            this.currentIndx = 0;
            foreach (TreeNode<StoryBase> sbNode in this.doc.StoryBoard)
            {
                foreach (Sample s in sbNode.Content.Samples)
                {
                    this.currentIndx = Math.Max(this.currentIndx, s.Id);
                }
            }
        }

    }
}
